snapshot: Track clip as a rect only
authorBenjamin Otte <otte@redhat.com>
Sat, 31 Mar 2018 15:22:48 +0000 (17:22 +0200)
committerBenjamin Otte <otte@redhat.com>
Thu, 5 Apr 2018 12:56:38 +0000 (14:56 +0200)
gtk/gskpango.c
gtk/gtkiconview.c
gtk/gtksnapshot.c
gtk/gtksnapshot.h
gtk/gtksnapshotprivate.h
gtk/gtkwidget.c

index 7e7fa73ebe0c75faa629a30ddd2278d861a00328..7c2aa4dee31f7557ab6d740b36bde5e332d7b42a 100644 (file)
@@ -126,25 +126,18 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer        *renderer,
   if (ink_rect.width == 0 || ink_rect.height == 0)
     return;
 
-  gtk_snapshot_get_offset (crenderer->snapshot, &x_offset, &y_offset);
-
   graphene_rect_init (&node_bounds,
-                      x_offset + (float)x/PANGO_SCALE,
-                      y_offset + (float)y/PANGO_SCALE + ink_rect.y,
+                      (float)x/PANGO_SCALE,
+                      (float)y/PANGO_SCALE + ink_rect.y,
                       ink_rect.x + ink_rect.width,
                       ink_rect.height);
 
-  /* Remove the snapshot offset from the position here again since
-   * gtk_snapshot_clips_rect will apply it to the given rect. */
-  if (gtk_snapshot_clips_rect (crenderer->snapshot,
-                               &(cairo_rectangle_int_t){
-                                 node_bounds.origin.x - x_offset,
-                                 node_bounds.origin.y - y_offset,
-                                 ceil (node_bounds.size.width),
-                                 ceil (node_bounds.size.height)
-                               }))
+  if (gtk_snapshot_clips_rect (crenderer->snapshot, &node_bounds))
     return;
 
+  gtk_snapshot_get_offset (crenderer->snapshot, &x_offset, &y_offset);
+  graphene_rect_offset (&node_bounds, x_offset, y_offset);
+
   get_color (crenderer, PANGO_RENDER_PART_FOREGROUND, &color);
 
   node = gsk_text_node_new_with_bounds (font,
index 4c431e1b96ed5bf3384278aac7234ab07ec5c10d..a9a9901bcb57406d439e2188ad73e66297b9ecda 100644 (file)
@@ -1684,12 +1684,13 @@ gtk_icon_view_snapshot (GtkWidget   *widget,
   for (icons = icon_view->priv->items; icons; icons = icons->next)
     {
       GtkIconViewItem *item = icons->data;
-      cairo_rectangle_int_t area;
+      graphene_rect_t area;
 
-      area.x = item->cell_area.x - icon_view->priv->item_padding;
-      area.y = item->cell_area.y      - icon_view->priv->item_padding;
-      area.width = item->cell_area.width  + icon_view->priv->item_padding * 2;
-      area.height = item->cell_area.height + icon_view->priv->item_padding * 2;
+      graphene_rect_init (&area,
+                          item->cell_area.x - icon_view->priv->item_padding,
+                          item->cell_area.y - icon_view->priv->item_padding,
+                          item->cell_area.width  + icon_view->priv->item_padding * 2,
+                          item->cell_area.height + icon_view->priv->item_padding * 2);
 
       if (!gtk_snapshot_clips_rect (snapshot, &area))
         {
index 4a0cdd9865f7b0724ce6b9feee4e8eef328de551..ead1e5acafe4b851d6c695878fa6c4456e8ad1a0 100644 (file)
@@ -81,22 +81,6 @@ gtk_snapshot_init (GtkSnapshot *self)
 {
 }
 
-static cairo_region_t *
-create_offset_region (const cairo_region_t *region,
-                      int                   dx,
-                      int                   dy)
-{
-  cairo_region_t *result;
-
-  if (region == NULL)
-    return NULL;
-
-  result = cairo_region_copy (region);
-  cairo_region_translate (result, -dx, -dy);
-
-  return result;
-}
-
 static GskRenderNode *
 gtk_snapshot_collect_default (GtkSnapshot       *snapshot,
                               GtkSnapshotState  *state,
@@ -127,7 +111,7 @@ gtk_snapshot_collect_default (GtkSnapshot       *snapshot,
 static GtkSnapshotState *
 gtk_snapshot_push_state (GtkSnapshot            *snapshot,
                          char                   *name,
-                         cairo_region_t         *clip,
+                         const graphene_rect_t  *clip,
                          int                     translate_x,
                          int                     translate_y,
                          GtkSnapshotCollectFunc  collect_func)
@@ -139,7 +123,10 @@ gtk_snapshot_push_state (GtkSnapshot            *snapshot,
 
   state->name = name;
   if (clip)
-    state->clip_region = cairo_region_reference (clip);
+    {
+      state->clip = *clip;
+      state->has_clip = TRUE;
+    }
   state->translate_x = translate_x;
   state->translate_y = translate_y;
   state->collect_func = collect_func;
@@ -168,14 +155,13 @@ gtk_snapshot_get_previous_state (const GtkSnapshot *snapshot)
 static void
 gtk_snapshot_state_clear (GtkSnapshotState *state)
 {
-  g_clear_pointer (&state->clip_region, cairo_region_destroy);
   g_clear_pointer (&state->name, g_free);
 }
 
 static GtkSnapshot *
-gtk_snapshot_new_internal (gboolean        record_names,
-                           cairo_region_t *clip,
-                           char           *name)
+gtk_snapshot_new_internal (gboolean               record_names,
+                           const graphene_rect_t *clip,
+                           char                  *name)
 {
   GtkSnapshot *snapshot;
 
@@ -235,7 +221,7 @@ gtk_snapshot_new_child (GtkSnapshot *parent,
 {
   GtkSnapshotState *parent_state;
   GtkSnapshot *snapshot;
-  cairo_region_t *clip;
+  graphene_rect_t c, *clip;
   char *str;
 
   if (name && parent->record_names)
@@ -250,17 +236,21 @@ gtk_snapshot_new_child (GtkSnapshot *parent,
     str = NULL;
 
   parent_state = gtk_snapshot_get_current_state (parent);
-  clip = create_offset_region (parent_state->clip_region,
-                               parent_state->translate_x,
-                               parent_state->translate_y);
+  if (parent_state->has_clip)
+    {
+      graphene_rect_offset_r (&parent_state->clip,
+                              - parent_state->translate_x,
+                              - parent_state->translate_y,
+                              &c);
+      clip = &c;
+    }
+  else
+    clip = NULL;
 
   snapshot = gtk_snapshot_new_internal (parent->record_names,
                                         clip,
                                         str);
 
-  if (clip)
-    cairo_region_destroy (clip);
-
   return snapshot;
 }
 
@@ -341,7 +331,7 @@ gtk_snapshot_push (GtkSnapshot           *snapshot,
 
       gtk_snapshot_push_state (snapshot,
                                g_strdup (str),
-                               state->clip_region,
+                               state->has_clip ? &state->clip : NULL,
                                state->translate_x,
                                state->translate_y,
                                gtk_snapshot_collect_default);
@@ -453,7 +443,7 @@ gtk_snapshot_push_offset (GtkSnapshot *snapshot)
 {
   GtkSnapshotState *state = gtk_snapshot_get_current_state (snapshot);
   char *str;
-  cairo_region_t *offset_clip;
+  graphene_rect_t clip;
 
   if (snapshot->record_names)
     {
@@ -462,17 +452,17 @@ gtk_snapshot_push_offset (GtkSnapshot *snapshot)
   else
     str = NULL;
 
-  offset_clip = create_offset_region (state->clip_region,
-                                      state->translate_x,
-                                      state->translate_y);
+  if (state->has_clip)
+    graphene_rect_offset_r (&state->clip,
+                            - state->translate_x,
+                            - state->translate_y,
+                            &clip);
 
   state = gtk_snapshot_push_state (snapshot,
                                    str,
-                                   offset_clip,
+                                   state->has_clip ? &clip : NULL,
                                    0, 0,
                                    gtk_snapshot_collect_offset);
-  if (offset_clip)
-    cairo_region_destroy (offset_clip);
 }
 
 static GskRenderNode *
@@ -531,7 +521,7 @@ gtk_snapshot_push_opacity (GtkSnapshot *snapshot,
 
   state = gtk_snapshot_push_state (snapshot,
                                    str,
-                                   current_state->clip_region,
+                                   current_state->has_clip ? &current_state->clip : NULL,
                                    current_state->translate_x,
                                    current_state->translate_y,
                                    gtk_snapshot_collect_opacity);
@@ -589,7 +579,7 @@ gtk_snapshot_push_blur (GtkSnapshot *snapshot,
 
   state = gtk_snapshot_push_state (snapshot,
                                    str,
-                                   current_state->clip_region,
+                                   current_state->has_clip ? &current_state->clip : NULL,
                                    current_state->translate_x,
                                    current_state->translate_y,
                                    gtk_snapshot_collect_blur);
@@ -675,11 +665,11 @@ gtk_snapshot_push_color_matrix (GtkSnapshot             *snapshot,
     str = NULL;
 
   state = gtk_snapshot_push_state (snapshot,
-                                  str,
-                                  current_state->clip_region,
-                                  current_state->translate_x,
-                                  current_state->translate_y,
-                                  gtk_snapshot_collect_color_matrix);
+                                   str,
+                                   current_state->has_clip ? &current_state->clip : NULL,
+                                   current_state->translate_x,
+                                   current_state->translate_y,
+                                   gtk_snapshot_collect_color_matrix);
 
   graphene_matrix_init_from_matrix (&state->data.color_matrix.matrix, color_matrix);
   graphene_vec4_init_from_vec4 (&state->data.color_matrix.offset, color_offset);
@@ -731,7 +721,6 @@ gtk_snapshot_push_repeat (GtkSnapshot           *snapshot,
 {
   const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
   GtkSnapshotState *state;
-  cairo_region_t *clip = NULL;
   graphene_rect_t real_child_bounds = { { 0 } };
   char *str;
 
@@ -747,16 +736,11 @@ gtk_snapshot_push_repeat (GtkSnapshot           *snapshot,
     str = NULL;
 
   if (child_bounds)
-    {
-      cairo_rectangle_int_t rect;
-      graphene_rect_offset_r (child_bounds, current_state->translate_x, current_state->translate_y, &real_child_bounds);
-      rectangle_init_from_graphene (&rect, &real_child_bounds);
-      clip = cairo_region_create_rectangle (&rect);
-    }
+    graphene_rect_offset_r (child_bounds, current_state->translate_x, current_state->translate_y, &real_child_bounds);
 
   state = gtk_snapshot_push_state (snapshot,
                                    str,
-                                   clip,
+                                   &real_child_bounds,
                                    current_state->translate_x,
                                    current_state->translate_y,
                                    gtk_snapshot_collect_repeat);
@@ -767,9 +751,6 @@ gtk_snapshot_push_repeat (GtkSnapshot           *snapshot,
   state->data.repeat.child_bounds = real_child_bounds;
 
   current_state = state;
-
-  if (clip)
-    cairo_region_destroy (clip);
 }
 
 static GskRenderNode *
@@ -810,8 +791,7 @@ gtk_snapshot_push_clip (GtkSnapshot           *snapshot,
 {
   const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
   GtkSnapshotState *state;
-  graphene_rect_t real_bounds;
-  cairo_region_t *clip;
+  graphene_rect_t clip, real_bounds;
   cairo_rectangle_int_t rect;
   char *str;
 
@@ -829,25 +809,19 @@ gtk_snapshot_push_clip (GtkSnapshot           *snapshot,
     str = NULL;
 
   rectangle_init_from_graphene (&rect, &real_bounds);
-  if (current_state->clip_region)
-    {
-      clip = cairo_region_copy (current_state->clip_region);
-      cairo_region_intersect_rectangle (clip, &rect);
-    }
+  if (current_state->has_clip)
+    graphene_rect_intersection (&current_state->clip, &real_bounds, &clip);
   else
-    {
-      clip = cairo_region_create_rectangle (&rect);
-    }
+    clip = real_bounds;
+
   state = gtk_snapshot_push_state (snapshot,
-                                  str,
-                                  clip,
-                                  current_state->translate_x,
-                                  current_state->translate_y,
-                                  gtk_snapshot_collect_clip);
+                                   str,
+                                   &clip,
+                                   current_state->translate_x,
+                                   current_state->translate_y,
+                                   gtk_snapshot_collect_clip);
 
   state->data.clip.bounds = real_bounds;
-
-  cairo_region_destroy (clip);
 }
 
 static GskRenderNode *
@@ -905,8 +879,7 @@ gtk_snapshot_push_rounded_clip (GtkSnapshot          *snapshot,
   const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
   GtkSnapshotState *state;
   GskRoundedRect real_bounds;
-  cairo_region_t *clip;
-  cairo_rectangle_int_t rect;
+  graphene_rect_t clip;
   char *str;
 
   gsk_rounded_rect_init_copy (&real_bounds, bounds);
@@ -923,29 +896,20 @@ gtk_snapshot_push_rounded_clip (GtkSnapshot          *snapshot,
   else
     str = NULL;
 
-  rectangle_init_from_graphene (&rect, &real_bounds.bounds);
-  if (current_state->clip_region)
-    {
-      clip = cairo_region_copy (current_state->clip_region);
-      cairo_region_intersect_rectangle (clip, &rect);
-    }
+  if (current_state->has_clip)
+    graphene_rect_intersection (&current_state->clip, &real_bounds.bounds, &clip);
   else
-    {
-      clip = cairo_region_create_rectangle (&rect);
-    }
+    clip = real_bounds.bounds;
 
   state = gtk_snapshot_push_state (snapshot,
-                                  str,
-                                  clip,
-                                  current_state->translate_x,
-                                  current_state->translate_y,
-                                  gtk_snapshot_collect_rounded_clip);
+                                   str,
+                                   &clip,
+                                   current_state->translate_x,
+                                   current_state->translate_y,
+                                   gtk_snapshot_collect_rounded_clip);
 
 
   state->data.rounded_clip.bounds = real_bounds;
-
-  current_state = state;
-  cairo_region_destroy (clip);
 }
 
 static GskRenderNode *
@@ -999,7 +963,7 @@ gtk_snapshot_push_shadow (GtkSnapshot            *snapshot,
 
   state = gtk_snapshot_push_state (snapshot,
                                    str,
-                                   current_state->clip_region,
+                                   current_state->has_clip ? &current_state->clip : NULL,
                                    current_state->translate_x,
                                    current_state->translate_y,
                                    gtk_snapshot_collect_shadow);
@@ -1102,7 +1066,7 @@ gtk_snapshot_push_blend (GtkSnapshot  *snapshot,
 
   top_state = gtk_snapshot_push_state (snapshot,
                                        str,
-                                       current_state->clip_region,
+                                       current_state->has_clip ? &current_state->clip : NULL,
                                        current_state->translate_x,
                                        current_state->translate_y,
                                        gtk_snapshot_collect_blend_top);
@@ -1110,7 +1074,7 @@ gtk_snapshot_push_blend (GtkSnapshot  *snapshot,
 
   gtk_snapshot_push_state (snapshot,
                            g_strdup (str),
-                           top_state->clip_region,
+                           top_state->has_clip ? &top_state->clip : NULL,
                            top_state->translate_x,
                            top_state->translate_y,
                            gtk_snapshot_collect_blend_bottom);
@@ -1227,7 +1191,7 @@ gtk_snapshot_push_cross_fade (GtkSnapshot *snapshot,
 
   end_state = gtk_snapshot_push_state (snapshot,
                                        str,
-                                       current_state->clip_region,
+                                       current_state->has_clip ? &current_state->clip : NULL,
                                        current_state->translate_x,
                                        current_state->translate_y,
                                        gtk_snapshot_collect_cross_fade_end);
@@ -1235,7 +1199,7 @@ gtk_snapshot_push_cross_fade (GtkSnapshot *snapshot,
 
   gtk_snapshot_push_state (snapshot,
                            g_strdup (str),
-                           end_state->clip_region,
+                           end_state->has_clip ? &end_state->clip : NULL,
                            end_state->translate_x,
                            end_state->translate_y,
                            gtk_snapshot_collect_cross_fade_start);
@@ -1499,18 +1463,8 @@ gtk_snapshot_append_cairo (GtkSnapshot           *snapshot,
 
   graphene_rect_offset_r (bounds, current_state->translate_x, current_state->translate_y, &real_bounds);
 
-  if (current_state->clip_region)
-    {
-      cairo_rectangle_int_t clip_extents;
-      cairo_region_get_extents (current_state->clip_region, &clip_extents);
-      graphene_rect_intersection (&GRAPHENE_RECT_INIT (
-                                    clip_extents.x,
-                                    clip_extents.y,
-                                    clip_extents.width,
-                                    clip_extents.height
-                                  ),
-                                  &real_bounds, &real_bounds);
-    }
+  if (current_state->has_clip)
+    graphene_rect_intersection (&current_state->clip, &real_bounds, &real_bounds);
 
   node = gsk_cairo_node_new (&real_bounds);
 
@@ -1617,18 +1571,8 @@ gtk_snapshot_append_color (GtkSnapshot           *snapshot,
   graphene_rect_offset_r (bounds, current_state->translate_x, current_state->translate_y, &real_bounds);
 
   /* Color nodes are trivially "clippable" so we do it now */
-  if (current_state->clip_region)
-    {
-      cairo_rectangle_int_t clip_extents;
-      cairo_region_get_extents (current_state->clip_region, &clip_extents);
-      graphene_rect_intersection (&GRAPHENE_RECT_INIT (
-                                    clip_extents.x,
-                                    clip_extents.y,
-                                    clip_extents.width,
-                                    clip_extents.height
-                                  ),
-                                  &real_bounds, &real_bounds);
-    }
+  if (current_state->has_clip)
+    graphene_rect_intersection (&current_state->clip, &real_bounds, &real_bounds);
 
   node = gsk_color_node_new (color, &real_bounds);
 
@@ -1660,21 +1604,21 @@ gtk_snapshot_append_color (GtkSnapshot           *snapshot,
  * Returns: %TRUE if @bounds is entirely outside the clip region
  */
 gboolean
-gtk_snapshot_clips_rect (GtkSnapshot                 *snapshot,
-                         const cairo_rectangle_int_t *rect)
+gtk_snapshot_clips_rect (GtkSnapshot           *snapshot,
+                         const graphene_rect_t *bounds)
 {
   const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
-  cairo_rectangle_int_t offset_rect;
+  graphene_rect_t offset_rect;
 
-  if (current_state->clip_region == NULL)
+  if (!current_state->has_clip)
     return FALSE;
 
-  offset_rect.x = rect->x + current_state->translate_x;
-  offset_rect.y = rect->y + current_state->translate_y;
-  offset_rect.width = rect->width;
-  offset_rect.height = rect->height;
+  graphene_rect_offset_r (bounds, 
+                          current_state->translate_x,
+                          current_state->translate_y,
+                          &offset_rect);
 
-  return cairo_region_contains_rectangle (current_state->clip_region, &offset_rect) == CAIRO_REGION_OVERLAP_OUT;
+  return !graphene_rect_intersection (&offset_rect, &current_state->clip, NULL);
 }
 
 /**
@@ -1852,19 +1796,8 @@ gtk_snapshot_append_linear_gradient (GtkSnapshot            *snapshot,
   real_end_point.y = end_point->y + current_state->translate_y;
 
   /* Linear gradients can be trivially clipped if we don't change the start/end points. */
-  if (current_state->clip_region)
-    {
-      cairo_rectangle_int_t clip_extents;
-
-      cairo_region_get_extents (current_state->clip_region, &clip_extents);
-      graphene_rect_intersection (&GRAPHENE_RECT_INIT (
-                                    clip_extents.x,
-                                    clip_extents.y,
-                                    clip_extents.width,
-                                    clip_extents.height
-                                  ),
-                                  &real_bounds, &real_bounds);
-    }
+  if (current_state->has_clip)
+    graphene_rect_intersection (&current_state->clip, &real_bounds, &real_bounds);
 
   node = gsk_linear_gradient_node_new (&real_bounds,
                                        &real_start_point,
@@ -1930,19 +1863,8 @@ gtk_snapshot_append_repeating_linear_gradient (GtkSnapshot            *snapshot,
   real_end_point.y = end_point->y + current_state->translate_y;
 
   /* Repeating Linear gradients can be trivially clipped if we don't change the start/end points. */
-  if (current_state->clip_region)
-    {
-      cairo_rectangle_int_t clip_extents;
-
-      cairo_region_get_extents (current_state->clip_region, &clip_extents);
-      graphene_rect_intersection (&GRAPHENE_RECT_INIT (
-                                    clip_extents.x,
-                                    clip_extents.y,
-                                    clip_extents.width,
-                                    clip_extents.height
-                                  ),
-                                  &real_bounds, &real_bounds);
-    }
+  if (current_state->has_clip)
+    graphene_rect_intersection (&current_state->clip, &real_bounds, &real_bounds);
 
   node = gsk_repeating_linear_gradient_node_new (&real_bounds,
                                                  &real_start_point,
index 05de9ab599810d23da16ab1ed9e86427bc2e0a73..14cb20470d51587befc3c27f43d26f82bd9d9d55 100644 (file)
@@ -169,7 +169,7 @@ void            gtk_snapshot_append_layout              (GtkSnapshot
 
 GDK_AVAILABLE_IN_ALL
 gboolean        gtk_snapshot_clips_rect                 (GtkSnapshot            *snapshot,
-                                                         const cairo_rectangle_int_t  *bounds);
+                                                         const graphene_rect_t  *bounds);
 
 GDK_AVAILABLE_IN_ALL
 void            gtk_snapshot_render_background          (GtkSnapshot            *snapshot,
index 3b1a145ae4b25c790e576ff825d3cc5ff8c1df48..e5ddb600f0cf538eedc6ac7506524804b713db00 100644 (file)
@@ -35,10 +35,12 @@ struct _GtkSnapshotState {
   guint                  start_node_index;
   guint                  n_nodes;
 
-  cairo_region_t        *clip_region;
+  graphene_rect_t        clip;
   int                    translate_x;
   int                    translate_y;
 
+  guint                  has_clip : 1;
+
   GtkSnapshotCollectFunc collect_func;
   union {
     struct {
index 14f121b31ab6b6d655e88dd9c17757d70941467a..3d9f967ce5b9caf758db35c7cf969857c1e0b743 100644 (file)
@@ -13815,7 +13815,7 @@ gtk_widget_snapshot (GtkWidget   *widget,
                      GtkSnapshot *snapshot)
 {
   GtkWidgetPrivate *priv = widget->priv;
-  cairo_rectangle_int_t offset_clip;
+  graphene_rect_t offset_clip;
   double opacity;
 
   if (!_gtk_widget_is_drawable (widget))
@@ -13828,9 +13828,11 @@ gtk_widget_snapshot (GtkWidget   *widget,
     }
 
   priv = widget->priv;
-  offset_clip = priv->clip;
-  offset_clip.x -= priv->allocation.x;
-  offset_clip.y -= priv->allocation.y;
+  graphene_rect_init (&offset_clip,
+                      priv->clip.x - priv->allocation.x,
+                      priv->clip.y - priv->allocation.y,
+                      priv->clip.width,
+                      priv->clip.height);
 
   if (gtk_snapshot_clips_rect (snapshot, &offset_clip))
     return;